WINDOWCLONE_BG_COLOR.from_pixel(0x000000f0);
const WINDOWCLONE_TITLE_COLOR = new Clutter.Color();
WINDOWCLONE_TITLE_COLOR.from_pixel(0xffffffff);
+const FRAME_COLOR = new Clutter.Color();
+FRAME_COLOR.from_pixel(0xffffffff);
// Define a layout scheme for small window counts. For larger
// counts we fall back to an algorithm. We need more schemes here
// in both zoomed-in and zoomed-out views; this is slightly
// metaphor-breaking, but the alternatives are also weird.
const GRID_SPACING = 15;
+const FRAME_SIZE = GRID_SPACING / 3;
function Workspace(workspaceNum) {
this._init(workspaceNum);
this._workspaceNum = workspaceNum;
this.actor = new Clutter.Group();
+ this.scale = 1.0;
let windows = global.get_windows().filter(this._isMyWindow, this);
this._overlappedMode = !((this._windows.length-1) in POSITIONS);
this._removeButton = null;
this._visible = false;
+
+ this._frame = null;
},
// Checks if the workspace is empty (ie, contains only a desktop window)
this.actor.disconnect(this._adjustRemoveButtonId);
},
+ // Mark the workspace selected/not-selected
+ setSelected : function(selected) {
+ if (selected) {
+ if (this._frame)
+ return;
+
+ // FIXME: do something cooler-looking using clutter-cairo
+ this._frame = new Clutter.Rectangle({ color: FRAME_COLOR });
+ this.actor.add_actor(this._frame);
+ this._frame.set_position(this._desktop.x - FRAME_SIZE / this.actor.scale_x,
+ this._desktop.y - FRAME_SIZE / this.actor.scale_y);
+ this._frame.set_size(this._desktop.width + 2 * FRAME_SIZE / this.actor.scale_x,
+ this._desktop.height + 2 * FRAME_SIZE / this.actor.scale_y);
+ this._frame.lower_bottom();
+
+ this._framePosHandler = this.actor.connect('notify::x', Lang.bind(this, this._updateFramePosition));
+ this._frameSizeHandler = this.actor.connect('notify::scale-x', Lang.bind(this, this._updateFrameSize));
+ } else {
+ if (!this._frame)
+ return;
+ this.actor.disconnect(this._framePosHandler);
+ this.actor.disconnect(this._frameSizeHandler);
+ this._frame.destroy();
+ this._frame = null;
+ }
+ },
+
+ _updateFramePosition : function() {
+ this._frame.set_position(this._desktop.x - FRAME_SIZE / this.actor.scale_x,
+ this._desktop.y - FRAME_SIZE / this.actor.scale_y);
+ },
+
+ _updateFrameSize : function() {
+ this._frame.set_size(this._desktop.width + 2 * FRAME_SIZE / this.actor.scale_x,
+ this._desktop.height + 2 * FRAME_SIZE / this.actor.scale_y);
+ },
+
// Animate the full-screen to overlay transition.
zoomToOverlay : function() {
let global = Shell.Global.get();
Workspaces.prototype = {
_init : function() {
- let me = this;
let global = Shell.Global.get();
this.actor = new Clutter.Group();
// Create and position workspace objects
for (let w = 0; w < global.screen.n_workspaces; w++) {
this._workspaces[w] = new Workspace(w);
- if (w == activeWorkspaceIndex)
+ if (w == activeWorkspaceIndex) {
activeWorkspace = this._workspaces[w];
+ activeWorkspace.setSelected(true);
+ }
this.actor.add_actor(this._workspaces[w].actor);
}
activeWorkspace.actor.raise_top();
// Track changes to the number of workspaces
this._nWorkspacesNotifyId =
global.screen.connect('notify::n-workspaces',
- function() {
- me._workspacesChanged();
- });
+ Lang.bind(this, this._workspacesChanged));
+ this._switchWorkspaceNotifyId =
+ global.window_manager.connect('switch-workspace',
+ Lang.bind(this, this._activeWorkspaceChanged));
},
hide : function() {
this._backdrop = null;
global.screen.disconnect(this._nWorkspacesNotifyId);
+ global.window_manager.disconnect(this._switchWorkspaceNotifyId);
},
// Assign grid positions to workspaces. We can't just do a simple
}
},
+ _activeWorkspaceChanged : function(wm, from, to, direction) {
+ this._workspaces[from].setSelected(false);
+ this._workspaces[to].setSelected(true);
+ },
+
_addWorkspace : function(actor, event) {
let global = Shell.Global.get();